home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
graphic
/
baspcx10.zip
/
BAS2PCX.C
next >
Wrap
C/C++ Source or Header
|
1991-03-09
|
8KB
|
397 lines
/*
* Bas2PCX -- Convert a BASIC BLOAD image to .PCX format
*
* Usage: bas2pcx <infile> [outfile]
*
* Where: <infile> = BLOAD image to load (.PIC extension default)
* [outfile] = .PCX file generated. If not specified
* input filename is used, with .PCX added.
*/
/* INCLUDES */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <dir.h>
#include <io.h>
#include <alloc.h>
#include <conio.h>
#include <mem.h>
#include <process.h>
/* DEFINES */
#define EGA_320_200_16 0x0D
#define graph_out(index, val) \
{ \
outp(0x3CE, index); \
outp(0x3CF, val ); \
}
#define seq_out(index, val) \
{ \
outp(0x3C4, index); \
outp(0x3C5, val ); \
}
/* TYPEDEFS */
typedef unsigned char UBYTE;
typedef int WORD;
typedef unsigned int UWORD;
typedef long LONG;
typedef unsigned long ULONG;
/* FUNCTIONS */
/*
* get_parms() - Crack the parameters passed in from the command line.
*/
void get_parms(int argc, char *argv[], char *fin, char *fout)
{
char drive[MAXDRIVE], dir[MAXDIR], file[MAXFILE], ext[MAXEXT];
/* The first parameter is the input file. Add .PIC extension if needed. */
fnsplit(argv[1], drive, dir, file, ext);
if(ext[0] == '\0')
strcpy(ext, ".PIC");
fnmerge(fin, drive, dir, file, ext);
/* Check for presence of next parameter */
if(argc == 3)
{
fnsplit(argv[2], drive, dir, file, ext);
if(ext[0] == '\0')
strcpy(ext, ".PCX");
}
else
strcpy(ext, ".PCX");
fnmerge(fout, drive, dir, file, ".PCX");
}
/*
* mode() - Set the video mode
*/
void mode(WORD mode)
{
_AH = 0;
_AL = mode;
geninterrupt(0x10);
}
/*
* cls() - Clear the screen to the given color
*/
void cls(WORD color)
{
union REGS r;
r.x.ax = 0x0600;
r.x.cx = 0x0000;
r.x.dx = 0x184F;
r.h.bh = color;
int86(0x10, &r, &r);
}
/*
* get_pixel() - Read a pixel from the BLOAD buffer.
*/
UBYTE get_pixel(UBYTE far *pic, int x, int y)
{
UBYTE byte;
UBYTE far *mem_addr;
mem_addr = pic + (y&0x01)*0x2000;
byte = *(mem_addr + ((y & 0xFE)>>1)*0x50 + x/4);
return((byte >> ((3-(x&0x03))<<1))&0x03);
}
/*
* put_pixel() - Write a pixel to the EGA video buffer
*/
void put_pixel(int x, int y, UBYTE color)
{
ULONG off;
UBYTE far *mem_addr;
int dummy, mask;
off = (LONG)y * 40L + ((LONG)x / 8L);
mem_addr = (UBYTE far *)(0xA0000000L + off);
mask = 0x80 >> (x % 8);
graph_out(8, mask);
graph_out(3, 0x00);
seq_out(2, 0x0F);
dummy = *mem_addr;
*mem_addr = 0;
seq_out(2, color);
*mem_addr = 0xFF;
seq_out(2, 0x0F);
graph_out(3, 0x00);
graph_out(8, 0xFF);
}
/*
* rd_byte() - Read a byte from the EGA screen, given the address of
* the byte and the color plane to read from.
*/
UBYTE rd_byte(ULONG addr, WORD clr_plane)
{
UBYTE far *mem_addr;
UBYTE pixel;
mem_addr = (UBYTE far *)(0xA0000000L + addr);
outp(0x3CE, 4);
outp(0x3CF, clr_plane);
outp(0x3CE, 5);
outp(0x3CF, 0);
pixel = *mem_addr;
return pixel;
}
/*
* farload_pic() - Load a BLOAD image into a buffer in RAM.
* Return a pointer to the buffer.
*/
UBYTE far *farload_pic(const char *file_name)
{
FILE *fp;
UBYTE far *buffer, *tbuff;
ULONG fsize;
if((fp = fopen(file_name,"rb")) == NULL)
{
printf("\nCan't find %s.\n",file_name);
return(0);
}
fsize = filelength(fileno(fp)) - 7;
buffer = (UBYTE far *)farcalloc(fsize, 1);
tbuff = (UBYTE *)calloc((int)fsize, 1);
fread((void *)tbuff, 1, 7, fp);
fread((void *)tbuff, 1, (int)fsize, fp);
movedata(FP_SEG(tbuff ), FP_OFF(tbuff ),
FP_SEG(buffer), FP_OFF(buffer), (int)fsize);
fclose(fp);
free((void *)tbuff);
return(buffer);
}
/*
* save_pcx() - Save the image on EGA page 0 to a .PCX file, using
* the default EGA palette
*/
void save_pcx(const char *fname)
{
FILE *fp;
UBYTE ch, old_ch, red, green, blue;
int i, j, k, add1, add2, number, num_out;
UBYTE color[16] = {
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
};
if((fp = fopen(fname, "wb")) == NULL)
{
printf("ERROR: failure to save %s.PCX\n", fname);
return;
}
/* Write out the standard ZSoft .PCX file header: */
fputc(0x0A, fp); /* Byte 0: 0x0A = ZSoft .PCX file */
fputc(0x05, fp); /* Byte 1: 0x05 = PC Paintbrush v3.0 */
fputc(0x01, fp); /* Byte 2: 0x01 = .PCX RLE coding */
fputc(0x01, fp); /* Byte 3: number of bits/pixel (1) */
putw( 0, fp); /* Bytes 4 - 5: window left */
putw( 0, fp); /* Bytes 6 - 7: window top */
putw(319, fp); /* Bytes 8 - 9: window right */
putw(199, fp); /* Bytes 10 - 11: window bottom */
putw(320, fp); /* Bytes 12 - 13: Horizontal resolution */
putw(200, fp); /* Bytes 14 - 15: Vertical resolution */
ch = 0x00;
/*
* Bytes 16 - 63: Color Map. This consists of 16 consecutive blocks
* of 3 bytes each: Redbyte, Greenbyte, Bluebyte.
*/
for(i=0 ; i<16 ; i++)
{
red = (((color[i] & 0x20)>>5) | ((color[i] & 0x04)>>1)) * 85;
green = (((color[i] & 0x10)>>4) | (color[i] & 0x02) ) * 85;
blue = (((color[i] & 0x08)>>3) | ((color[i] & 0x01)<<1)) * 85;
fputc(red , fp);
fputc(green, fp);
fputc(blue , fp);
}
fputc(0x00, fp); /* Byte 64: Reserved */
fputc(0x04, fp); /* Byte 65: Number of planes (4) */
putw(40, fp); /* Bytes 66-67: Bytes per line */
putw(0x01, fp); /* Bytes 68-69: 1 = color palette */
for(i=70 ; i<128 ; i++) /* Bytes 70 - 127 are unused */
fputc(0x00, fp);
for(k=0 ; k<200 ; k++)
{
add1 = 40 * k;
add2 = 0;
number = 1;
j = 0;
old_ch = rd_byte(add1+(add2++), 0);
for(i=add2 ; i<161 ; i++)
{
if(i == 160)
ch = old_ch-1;
else
{
if(add2 == 40)
{
j++;
add2 = 0;
}
ch = rd_byte(add1 + add2, j);
}
if((ch==old_ch) && number<63)
number++;
else
{
num_out = ((UBYTE)number | 0xC0);
if((number != 1) || ((old_ch&0xC0)==0xC0))
fputc(num_out, fp);
fputc(old_ch, fp);
old_ch = ch;
number = 1;
}
add2++;
}
}
fclose(fp);
}
/* MAIN */
void main(int argc, char *argv[])
{
int x, y;
char fin[MAXPATH], fout[MAXPATH];
UBYTE far *picbuf; /* image buffer */
UBYTE ega_color[4] = { 0, 11, 13, 15 }; /* EGA pos for CGA pal 0 */
if(argc==1 || argc>3)
{
printf("Usage: bas2pcx <infile> [outfile]\n\n");
printf("Where: <infile> = BLOAD image to load (.PIC extension default)\n");
printf(" [outfile] = .PCX file generated. If not specified\n");
printf(" input filename is used, with .PCX added.\n");
exit(0);
}
get_parms(argc, argv, fin, fout);
if((picbuf = farload_pic(fin)) == NULL)
exit(-1);
mode(EGA_320_200_16);
for(y=0 ; y<200 ; y++)
for(x=0 ; x<320 ; x++)
put_pixel(x, y, ega_color[get_pixel(picbuf, x, y)]);
putch(7);
farfree((void far *)picbuf);
save_pcx(fout);
putch(7);
getch();
mode(0x03);
}